package com.ruoyi.service.impl;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.entity.CouponDto;
import com.ruoyi.entity.VerSkuCouponRelate;
import com.ruoyi.mapper.ProductSkusMapper;
import com.ruoyi.mapper.VerCouponGroupsMapper;
import com.ruoyi.mapper.VerCouponsMapper;
import com.ruoyi.mapper.VerSkuCouponRelatesMapper;
import com.ruoyi.order.domain.VerCoupon;
import com.ruoyi.product.domain.ProductSku;
import com.ruoyi.service.VerCouponsService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class VerCouponsServiceImpl implements VerCouponsService {
    @Resource
    private VerCouponsMapper couponsMapper;
    @Resource
    private VerSkuCouponRelatesMapper verSkuCouponRelatesMapper;
    @Autowired
    private ProductSkusMapper productSkusMapper;

    @Override
    public CouponDto getCouponById(Long id){
        VerCoupon coupon = couponsMapper.selectById(id);
        if (coupon == null) {
            throw new ServiceException("优惠券不存在");
        }
        return convertToDTO(coupon);
    }

    @Override
    public List<CouponDto> getCouponsByGroupId(Long groupId) {
        List<VerCoupon> coupons = couponsMapper.selectByGroupId(groupId);
        return coupons.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    public List<CouponDto> getAvailableCoupons(VerCoupon verCoupon) {
        List<VerCoupon> coupons = couponsMapper.selectAvailableCoupons(verCoupon);
        return coupons.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public Long createCoupon(VerCoupon coupon) {
        // 设置默认值
        coupon.setStatus(0L); // 未使用
        coupon.setIsDelete(0);
        coupon.setCreateTime(new Date());

        // 生成唯一的优惠券编号
        if (coupon.getCode() == null || coupon.getCode().isEmpty()) {
            coupon.setCode(generateUniqueCouponCode());
        }

        int result = couponsMapper.insert(coupon);
        if (result <= 0) {
            throw new ServiceException("创建优惠券失败");
        }
        return coupon.getId();
    }

    /**
     * 生成唯一的优惠券编号
     * @return 唯一的优惠券编号
     */
    private String generateUniqueCouponCode() {
        String code;
        VerCoupon existingCoupon;
        do {
            // 生成8位随机字母数字组合的优惠券编号
            code = "CP" + System.currentTimeMillis() + String.format("%04d", (int)(Math.random() * 10000));
            existingCoupon = couponsMapper.selectByCode(code);
        } while (existingCoupon != null);

        return code;
    }

    @Override
    @Transactional
    public boolean updateCoupon(VerCoupon coupon) {
        coupon.setUpdateTime(new Date());
        int result = couponsMapper.update(coupon);
        return result > 0;
    }

    @Override
    @Transactional
    public boolean deleteCoupon(Long id) {
        // 先删除关联关系
        verSkuCouponRelatesMapper.deleteByCouponId(id);
        // 再删除优惠券本身
        int result = couponsMapper.deleteById(id);
        return result > 0;
    }

    @Override
    public boolean receiveCoupon(Long couponId) {
        // 检查优惠券状态
        VerCoupon coupon = couponsMapper.selectById(couponId);
        if (coupon == null) {
            throw new ServiceException("优惠券不存在");
        }

        // 检查是否已过期
        Date now = new Date();
        if (now.before(coupon.getStartTime()) || now.after(coupon.getEndTime())) {
            throw new ServiceException("优惠券不在有效期内");
        }

        // 检查是否还有库存
        if (coupon.getCouponStock() <= 0) {
            throw new ServiceException("优惠券已领完");
        }

        // 扣减库存
        int result = couponsMapper.decreaseStock(couponId);
        if (result <= 0) {
            throw new ServiceException("领取优惠券失败");
        }

        // 更新领取时间
        coupon.setGetTime(now);
        couponsMapper.update(coupon);

        return true;
    }

    @Override
    @Transactional
    public boolean useCoupon(Long couponId, Long orderId) {
        VerCoupon coupon = couponsMapper.selectById(couponId);
        if (coupon == null) {
            throw new ServiceException("优惠券不存在");
        }

        // 检查状态
        if (coupon.getStatus() != 0) {
            throw new ServiceException("优惠券不可用");
        }

        // 检查有效期
        Date now = new Date();
        if (now.after(coupon.getEndTime())) {
            throw new ServiceException("优惠券已过期");
        }

        // 更新状态和使用订单ID
        coupon.setStatus(1L); // 已使用
        coupon.setUseOrderId(String.valueOf(orderId));
        coupon.setUpdateTime(new Date());

        int result = couponsMapper.update(coupon);
        return result > 0;
    }

    @Override
    @Transactional
    public boolean relateSkuWithCoupon(Long couponId, List<Long> skuIds) {
        // 查询当前优惠券已关联的 SKU ID 列表
        List<Long> existingSkuIds = verSkuCouponRelatesMapper.selectSkuIdsByCouponId(couponId);

        // 去除已存在的 SKU，避免重复插入
        List<Long> newSkuIds = skuIds.stream()
                .filter(skuId -> !existingSkuIds.contains(skuId))
                .collect(Collectors.toList());

        if (newSkuIds.isEmpty()) {
            return true; // 没有新增
        }

        // 插入新的关联
        LocalDateTime now = LocalDateTime.now();
        List<VerSkuCouponRelate> relations = newSkuIds.stream()
                .map(skuId -> {
                    VerSkuCouponRelate relation = new VerSkuCouponRelate();
                    relation.setSkuId(skuId);
                    relation.setCouponId(couponId);
                    relation.setCreateTime(new Date());
                    relation.setUpdateTime(new Date());
                    relation.setIsDelete(0);
                    return relation;
                })
                .collect(Collectors.toList());

        verSkuCouponRelatesMapper.batchInsertRelations(relations);
        return true;
    }

//    @Override
//    @Transactional
//    public boolean relateSkuWithCoupon(Long couponId, List<Long> skuIds) {
//        // 先解除已有的关联
//        verSkuCouponRelatesMapper.deleteByCouponId(couponId);
//        // 批量添加新关联
//        LocalDateTime now = LocalDateTime.now();
//        List<VerSkuCouponRelate> relations = skuIds.stream()
//                .map(skuId -> {
//                    VerSkuCouponRelate relation = new VerSkuCouponRelate();
//                    relation.setSkuId(skuId);
//                    relation.setCouponId(couponId);
//                    relation.setCreateTime(new Date());
//                    relation.setUpdateTime(new Date());
//                    relation.setIsDelete(0);
//                    return relation;
//                })
//                .collect(Collectors.toList());
//
//        if (!relations.isEmpty()) {
//            verSkuCouponRelatesMapper.batchInsertRelations(relations);
//        }
//        return true;
//    }

    @Override
    public List<CouponDto> getUsableCouponsForSku(Long skuId, BigDecimal orderAmount) {
        // 查询该SKU关联的所有优惠券
        List<Long> couponIds = verSkuCouponRelatesMapper.selectCouponIdsBySkuId(skuId);
        if (couponIds.isEmpty()) {
            return List.of();
        }

        // 查询优惠券详情
        List<VerCoupon> coupons = couponsMapper.selectByIds(couponIds);

        // 筛选可用优惠券
        Date now = new Date();
        return coupons.stream()
                .filter(coupon -> {
                    // 状态为未使用
                    boolean statusValid = coupon.getStatus() == 0;
                    // 在有效期内
                    boolean timeValid = now.after(coupon.getStartTime()) && now.before(coupon.getEndTime());
                    // 满足使用门槛
                    boolean amountValid = orderAmount.compareTo(coupon.getMinAmount()) >= 0;
                    // 有库存
                    boolean stockValid = coupon.getCouponStock() > 0;

                    return statusValid && timeValid && amountValid && stockValid;
                })
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    public boolean autoUpdateCouponStatus() {
        // 获取当前时间
        Date now = new Date();

        // 查找已过期但状态不是"已过期"的优惠券
        List<VerCoupon> expiredCoupons = couponsMapper.selectExpiredCoupons(now);

        boolean result = true;
        for (VerCoupon coupon : expiredCoupons) {
            // 更新状态为已过期（状态码2）
            int updateResult = couponsMapper.updateStatus(coupon.getId(), 2);
            if (updateResult <= 0) {
                result = false;
            }
        }

        return result;
    }

    @Override
    public boolean removeSkuCouponRelation(Long couponId, List<Long> skuIds) {
        // 删除指定的关联关系
        int result = verSkuCouponRelatesMapper.deleteByCouponIdAndSkuIds(couponId, skuIds);
        return result > 0;
    }

    /**
     * 转换为DTO对象
     */
    private CouponDto convertToDTO(VerCoupon coupon) {
        // 在查询时自动更新优惠券状态
        VerCoupon updatedCoupon = autoUpdateCouponStatusIfNeeded(coupon);
        CouponDto dto = new CouponDto();
        BeanUtils.copyProperties(updatedCoupon, dto);
        // 查询关联的SKU信息
        List<Long> skuIds = verSkuCouponRelatesMapper.selectSkuIdsByCouponId(coupon.getId());
        if (!skuIds.isEmpty()) {
            List<ProductSku> skus = productSkusMapper.selectByIds(skuIds);
            dto.setSkus(skus);
        }
        return dto;
    }
    /**
     * 自动更新优惠券状态
     * @param coupon 原始优惠券
     * @return 更新后的优惠券
     */
    private VerCoupon autoUpdateCouponStatusIfNeeded(VerCoupon coupon) {
        // 如果优惠券状态不是"已使用"也不是"已过期"，但当前时间已经超过结束时间，则更新状态为"已过期"
        if (coupon.getStatus() != null && coupon.getStatus() != 1L && coupon.getStatus() != 2L && coupon.getEndTime() != null) {
            Date now = new Date();
            if (now.after(coupon.getEndTime())) {
                // 更新状态为已过期（状态码2）
                coupon.setStatus(2L);
                couponsMapper.updateStatus(coupon.getId(), 2);
            }
        }
        return coupon;
    }
}
